#!BPY
__doc__ = """
OLib.py
Rev 0.006
This module setups up a scene for static rendering, animation or game engine operation
This module provides useful library functions.

This module does nothing from the Blender command line

------------------
History:
rev 0.001 8/2/2009
   Initial release to test structure and functionality
	edt 
rev 0.002 8/8/2009
   Added cylinder object to image class
   Added block object to image class
   Modified the rendering context to get shadows to work correctly
	edt 
rev 0.003 8/8/2009
	edt 
rev 0.004 8/15/2009
    Migrated to hg & google code for version control
rev 0.005 8/23/2009
	Tubes & curves now work
rev 0.006 8/23/2009
	Adding lighting controls
"""

__author__ = "edt"
__version__ = "0.005 2009/08/23"
__url__="Website, dataOrigami.blogspot.com"
##############################################################

__doc__ = """
This module setups up a scene for static rendering, animation or game engine operation
This module imports useful library functions.

rev 0.005 8/23/09
"""

	
import Blender
import Blender.Mathutils
from Blender.Mathutils import *
import sys
import os
from math import *


#--------------------------------------------------------------		

class Point(object):
	def __init__(self,x,y,z):
		self.x = x
		self.y = y
		self.z = z

#--------------------------------------------------------------		
# functions used by the addXXXXLine methods to control the amount of 
#	curvature in a list of points rendered in a curve

def _smoothnessFunction00(dirLeft,dirRight,sFactor=1,
		index=0,closed=False):
	return dirLeft*0.5,dirRight*0.5

def _smoothnessFunction01(dirLeft,dirRight,sFactor=1,
		index=0,closed=False):
	dir = 0.4*(-dirLeft+dirRight)/2.0	
	return -dir,dir		

#--------------------------------------------------------------		
	
class Image(object):
	def __init__(self,name='Scene'):
		# create new scene
		scene = Blender.Scene.New(name)
		scene.makeCurrent()
		self.scene=scene
		##############################################################
		# add a camera and set it up
		#
		camdata = Blender.Camera.New() 
		cam = scene.objects.new(camdata) 
		# use setLocation to control the position of the camera
		scene.objects.camera = cam
		self.cam   = cam
		self._lookAt_x = 0
		self._lookAt_y = 0
		self._lookAt_z = 0
		self.lookFrom(2.481,-1.508,1.1)
		##############################################################
		# add a lamp and set it up
		#
		lampData = Blender.Lamp.New() 
		lampData.setEnergy(1.0) 
		lampData.setType('Lamp')
		lampData.mode |= Blender.Lamp.Modes["RayShadow"]  # make shadows appear
		lamp = scene.objects.new(lampData) 
		lamp.setLocation(2.0,2.0,5.0) 
		lamp.setEuler(120*(3.1415/180),30*(3.1415/180),-30*(3.1415/180))
		#
		################################################################
		# setup world
		world = Blender.World.New(name+'_World')
		world.setCurrent()
		
		################################################################
		# setup rendering
		context = scene.getRenderingContext()
		context.enableShadow(1)
		context.enableRayTracing(1)
		
		
		self.scene = scene
		self.lamp  = lamp
		self.usesDefaultLighting = True
		self.world = world
	
	def lookFrom(self,*args):
		if len(args)==1:
			# we have an object which contains look information
			x = args[0].x
			y = args[0].y
			z = args[0].z
		elif len(args)==3:
			# we have x,y,z coordinates
			x = args[0]
			y = args[1]
			z = args[2]
		# set camera position to x,y,z	
		self.cam.setLocation(x,y,z)
		self.lookAt()
	
	def lookAt(self,*args):
		if len(args)==0:
			to_x = self._lookAt_x
			to_y = self._lookAt_y
			to_z = self._lookAt_z
			up_x = 0
			up_y = 1
			up_z = 0
		elif len(args)==1:
			# we have an object which contains look information
			to_x = args[0].x
			to_y = args[0].y
			to_z = args[0].z
			up_x = 0
			up_y = 1
			up_z = 0
		elif len(args)==2:
			# we have an object which contains look information
			to_x = args[0].x
			to_y = args[0].y
			to_z = args[0].z
			up_x = args[1].x
			up_y = args[1].y
			up_z = args[1].z
		elif len(args)==3:
			# we have x,y,z coordinates
			to_x = args[0]
			to_y = args[1]
			to_z = args[2]
			up_x = 0
			up_y = 1
			up_z = 0
		elif len(args)==6:
			# we have x,y,z coordinates
			to_x = args[0]
			to_y = args[1]
			to_z = args[2]
			up_x = args[3]
			up_y = args[4]
			up_z = args[5]
		# save view target
		self._lookAt_x = to_x
		self._lookAt_y = to_y
		self._lookAt_z = to_z
		# set camera position to x,y,z	
		from_x, from_y, from_z = self.cam.getLocation()
		p1 = Vector([from_x,from_y,from_z])
		p2 = Vector([to_x,to_y,to_z])
		
		# form a vector that points in the direction from p1 to p2
		dir = p2-p1                  
		
		dir.normalize()
		up = Vector([up_x,up_y,up_z])
		up.normalize()
		dir_ref = Vector([0,0,-1.0])   # direction the camera naturally points w/o rotation
		if True: #abs(AngleBetweenVecs(dir,dir_ref))>1e-6:
			d = -dir
			d.normalize()
			#e = up-up*DotVecs(dir,up)
			#e = up-up*DotVecs(d,up)
			#e.normalize()
			#f = -CrossVecs(d,e)
			#f.normalize()
			f = CrossVecs(up,d)
			f.normalize()
			e = CrossVecs(d,f)
			e.normalize()
			A = Matrix(
					[f[0],f[1],f[2],0],
					[e[0],e[1],e[2],0],
					[d[0],d[1],d[2],0],
					[from_x,from_y,from_z,1])
		else:
			# the direction of view is parallel to the z-axis
			A = Matrix(
					[1,0,0,0],
					[0,1,0,0],
					[0,0,1,0],
					[from_x,from_y,from_z,1])	
		# apply the transform to the camera			
		print
		print A.toEuler()
		print A
		self.cam.setMatrix(A)
		#self.scene.getCurrentCamera().setMatrix(A)
		self.scene.objects.camera.setMatrix(A)
		print
		print self.cam.getMatrix()

	def addLighting(self,**kwargs):
		self.usesDefaultLighting = False
		self.delete(self.lamp)
		#
		loc      = kwargs.get('location',[1,1,3])
		target   = kwargs.get('target',[0,0,0])
		verts    = kwargs.get('verts',8)
		name     = kwargs.get('name','lamp')
		col      = kwargs.get('color',[1.0,1.0,1.0])
		type     = kwargs.get('type','Lamp')
		dist     = kwargs.get('distance',5.0)
		energy   = kwargs.get('energy',0.2)
		

		##############################################################
		# add a lamp and set it up
		#
		lampData = Blender.Lamp.New() 
		lampData.setEnergy(energy) 
		lampData.setType(type)
		lampData.mode |= Blender.Lamp.Modes["RayShadow"]  # make shadows appear
		lampData.R = col[0]
		lampData.G = col[1]
		lampData.B = col[2]
		lampData.dist = dist
		lamp = self.scene.objects.new(lampData) 
		#
		# default the values

		# use the class constructors from Blender to form vectors for p1 and p2
		p1 = Vector(loc)
		p2 = Vector(target)
		
		# form a vector that points in the direction from p1 to p2
		dir = p1-p2                  
		
		# get the length of the line we want that goes from p1 to p2
		length = dir.length
	
		dir.normalize()
		u = dir
		uu = Vector([0,0,1.0])
		print AngleBetweenVecs(u,uu)
		if abs(fmod(AngleBetweenVecs(u,uu),180.0))>1e-4:
			# the direction of the line is different
			# from the z-axis
			# find the orthonormal basis
			v = CrossVecs(u,uu)	
			w = CrossVecs(u,v)
			# form the transform matrix: 
			#   > The first 3 rows and 3 columns form
			#   a rotation matrix because the any vertex transformed by this 
			#   matrix will be the same distance from the origin as the original
			#   vertex. If this property is not preserved, then any shape formed 
			#   will be skewed and scaled by the transform.
			#   > The first 3 columns in the last row define the translation
			#   applied to any vertex. In this function, the translation move the 
			#   moves the end of the cylinder to the origin, then moves the end
			#   to p1.
			A = Matrix(
					[w[0],w[1],w[2],0],
					[v[0],v[1],v[2],0],
					[u[0],u[1],u[2],0],
					[p1[0],p1[1],p1[2],1])
		else:
			# the direction of the line is parallel to the z-axis
			# see the notes above on how the matrix is formed.
			A = Matrix(
					[1,0,0,0],
					[0,1,0,0],
					[0,0,1,0],
					[p1[0],p1[1],p1[2],1])	
		lamp.setMatrix(A)
		return lamp
		
	def add(self,item,name='noName'):
		# this method allows any object to be added to the scene
		ob = self.scene.objects.new(item,name)
		return ob
		
	def delete(self,item):
		"""
		Remove an object from the scene
		"""
		self.scene.objects.unlink(item)
	
	def _ModifyObject(self,ob,obData,**kwargs):
		loc   = kwargs.get('location',[0,0,0])
		col   = kwargs.get('color',[1.0,1.0,1.0])
		mat   = kwargs.get('mat',None)
		if mat==None:
			#print 'Coloring object'
			#print col
			mat=Blender.Material.New('Mat')
			mat.rgbCol = col
			#print mat
		#print ob.data
		#print ob.name
		obData.materials = [mat]	
		#ob.data.setMaterials([mat])
		#print ob.data.getMaterials()
		ob.setLocation(loc)
	
	def addSphere(self,**kwargs):
		# default the values
		diameter = kwargs.get('diameter',1.0)
		segments = kwargs.get('segments',8)
		rings = kwargs.get('rings',8)
		#loc   = kwargs.get('location',[0,0,0])
		useIco = kwargs.get('useIco',False)
		useUV = kwargs.get('useUV',True)
		subdivisions = kwargs.get('subdivisions',2)
		name = kwargs.get('name','sphere')
		#col   = kwargs.get('color',[1.0,1.0,1.0])
		if useIco:
			sphere = Blender.Mesh.Primitives.Icosphere(subdivisions,diameter)
		else:	
			sphere = Blender.Mesh.Primitives.UVsphere(segments,rings,diameter)
		#colorize the cylinder
		#mat=Blender.Material.New('sphereMat')
		#mat.rgbCol = col
		#sphere.materials += [mat]
		ob = self.add(sphere,name)		
		#ob.setLocation(loc)
		self._ModifyObject(ob,sphere,**kwargs)
		return ob
		
	def addCylinder(self,**kwargs):
		"""
		This function add a cylinder that goes from p1 to p2. 
		The points can be passes as either blender vectors or lists of [x,y,z] points.
		Optionally the diameter and number of vertices used to describe the cylinder are passed.
		-------------------
		The cylinder is formed by creating a Blender cylinder with a length equal to the distance
		point p1 and p2. The cylinder is then oriented using the transform matrix to rotate
		and translate it. 
		"""
		# default the values
		diameter = kwargs.get('diameter',0.1)
		p1       = kwargs.get('p1',[0,0,0])
		p2       = kwargs.get('p2',[0,0,1])
		verts    = kwargs.get('verts',8)
		#loc      = kwargs.get('location',[0,0,0])
		name     = kwargs.get('name','cylinder')
		#col      = kwargs.get('color',[1.0,1.0,1.0])
		closed   = kwargs.get('endCaps',True)

		# use the class constructors from Blender to form vectors for p1 and p2
		p1 = Vector(p1)
		p2 = Vector(p2)
		
		# form a vector that points in the direction from p1 to p2
		dir = p2-p1                  
		
		# get the length of the line we want that goes from p1 to p2
		length = dir.length

		# use Mesh.Primitives.Cylinder to create a mesh for the line
		if closed:
			me = Blender.Mesh.Primitives.Cylinder(verts,diameter,length)
		else:
			me = Blender.Mesh.Primitives.Tube(verts,diameter,length)
		
		###############
		# in the next few steps, the direction vector is used to form a basis
		#      see http://en.wikipedia.org/wiki/Basis_(linear_algebra)
		# which allows us to create a transform matrix to rotate the cylinder 
		# along the direction we want. The basic idea is that the vector from
		# p1 to p2 points in the direction we want. The cylinder created by 
		# Mesh.Primitives.Cylinder is oriented along the z-axis. To rotate the 
		# cylinder, we 	# rotate the z-axis in this direction. To completely specify
		# how to rotate, we need to provide information on how to rotate the x and y axes. 
		# To define this, a matrix which is orthonormal (see http://en.wikipedia.org/wiki/Orthonormal)
		# is created from the direction vector. To create the other vectors in the 
		# orthonormal basis, cross products are used to find orthogonal vectors.
		# 
		# use the normalize function to set the length of the direction vector to 1
		dir.normalize()
		u = dir
		uu = Vector([0,0,1.0])
		print AngleBetweenVecs(u,uu)
		if abs(fmod(AngleBetweenVecs(u,uu),180.0))>1e-4:
			# the direction of the line is different
			# from the z-axis
			# find the orthonormal basis
			v = CrossVecs(u,uu)	
			w = CrossVecs(u,v)
			# form the transform matrix: 
			#   > The first 3 rows and 3 columns form
			#   a rotation matrix because the any vertex transformed by this 
			#   matrix will be the same distance from the origin as the original
			#   vertex. If this property is not preserved, then any shape formed 
			#   will be skewed and scaled by the transform.
			#   > The first 3 columns in the last row define the translation
			#   applied to any vertex. In this function, the translation move the 
			#   moves the end of the cylinder to the origin, then moves the end
			#   to p1.
			A = Matrix(
					[w[0],w[1],w[2],0],
					[v[0],v[1],v[2],0],
					[u[0],u[1],u[2],0],
					[dir[0]/2.0*length+p1[0],dir[1]/2.0*length+p1[1],
						dir[2]/2.0*length+p1[2],1])
		else:
			# the direction of the line is parallel to the z-axis
			# see the notes above on how the matrix is formed.
			A = Matrix(
					[1,0,0,0],
					[0,1,0,0],
					[0,0,1,0],
					[dir[0]/2.0*length+p1[0],dir[1]/2.0*length+p1[1],
						dir[2]/2.0*length+p1[2],1])	

		# apply the transform to the cylinder			
		me.transform(A,True)

		#colorize the cylinder
		#mat=Blender.Material.New('cylinderMat')
		#mat.rgbCol = col
		#me.materials += [mat]
		ob = self.add(me,name)		
		#ob.setLocation(loc)
		self._ModifyObject(ob,me,**kwargs)
		return ob		
		
	def addBlock(self,**kwargs):
		# default the values
		p1 = kwargs.get('c1',[-1,-1,-1])
		p2 = kwargs.get('c2',[1,1,1])
		name = kwargs.get('name','cube')
		#col   = kwargs.get('color',[1.0,1.0,1.0])
		me = Blender.Mesh.Primitives.Cube(1.0)
		A = Matrix(
				[p2[0]-p1[0],0,0,0],
				[0,p2[1]-p1[1],0,0],
				[0,0,p2[2]-p1[2],0],
				[0,0,0,1])
		# apply the transform to the cube			
		me.transform(A,True)		
		B = Matrix(
				[1,0,0,0],
				[0,1,0,0],
				[0,0,1,0],
				[(p1[0]+p2[0])/2.0,
					(p1[1]+p2[1])/2.0,
						(p1[2]+p2[2])/2.0,1])
		me.transform(B,True)		
		#colorize the cylinder
		#mat=Blender.Material.New('cubeMat')
		#mat.rgbCol = col
		#me.materials += [mat]
		ob = self.add(me,name)		
		self._ModifyObject(ob,me,**kwargs)
		return ob

		
		
	def addSquare(self,**kwargs):
		# default the values
		p1 = kwargs.get('c1',[-1,-1,-1])
		p2 = kwargs.get('c2',[1,1,1])
		name = kwargs.get('name','square')
		diagVec = (Vector(p1)-Vector(p2))
		diagLen = diagVec.length
		me = Blender.Mesh.Primitives.Plane(diagLen)
		if False:
			# TODO: Add matrix transformations to get square properly positioned
			A = Matrix(
					[p2[0]-p1[0],0,0,0],
					[0,p2[1]-p1[1],0,0],
					[0,0,p2[2]-p1[2],0],
					[0,0,0,1])
			# apply the transform to the cube			
			#me.transform(A,True)		
			B = Matrix(
					[1,0,0,0],
					[0,1,0,0],
					[0,0,1,0],
					[(p1[0]+p2[0])/2.0,
						(p1[1]+p2[1])/2.0,
							(p1[2]+p2[2])/2.0,1])
			me.transform(B,True)		
			#colorize the cylinder
			#mat=Blender.Material.New('cubeMat')
			#mat.rgbCol = col
			#me.materials += [mat]
		ob = self.add(me,name)		
		self._ModifyObject(ob,me,**kwargs)
		return ob

	
	def addGrid(self,**kwargs):
		pass
		
	def addSurface(self,**kwargs):
		pass
	
	
	def addText(self,**kwargs):
		loc   = kwargs.get('location',[0,0,0])
		name  = kwargs.get('name','sphere')
		txtStr= kwargs.get('text','Default Message')
		width = kwargs.get('width',1.0)
		height= kwargs.get('height',1.0)
		col   = kwargs.get('color',[1.0,1.0,1.0])
		align = kwargs.get('align','LEFT')
		txt = Blender.Text3d.New()
		txt.setText(txtStr)
		txt.setSize(0.1)
		alignDict = {'LEFT':Blender.Text3d.LEFT,'RIGHT':Blender.Text3d.RIGHT,
					 'MIDDLE':Blender.Text3d.MIDDLE, 'FLUSH':Blender.Text3d.FLUSH}
		txt.setAlignment(alignDict[align])
		#mat=Blender.Material.New('textMat')
		#mat.rgbCol = col
		ob = self.add(txt)
		me = Blender.Mesh.New('textMesh')
		me.getFromObject(ob)
		#me.materials += [mat]
		self.delete(ob)
		newOb = self.add(me,name)
		
		# force a redraw to ensure that the bounding box is updated!!
		Blender.Window.RedrawAll() 
		boundBox = newOb.getBoundBox(1)
		upperBox = max(boundBox)
		lowerBox = min(boundBox)
		initialWidth = upperBox[0]-lowerBox[0]
		initialHeight = upperBox[1]-lowerBox[1]
		widthRatio = width/initialWidth
		heightRatio = height/initialHeight
		ratio = min(widthRatio,heightRatio)
		
		newOb.setSize(ratio,ratio,ratio)
		self._ModifyObject(newOb,me,**kwargs)
		#newOb.setLocation(loc)
		return newOb

	def _bezList2Curve(self,bezier_vecs):
		   '''
		   Take a list or vector triples and converts them into a bezier curve object
		   '''
		   
		   def bezFromVecs(vecs):
				   '''
				   Bezier triple from 3 vecs, shortcut functon
				   '''
				   bt= Blender.BezTriple.New(vecs[0].x, vecs[0].y, vecs[0].z,                        
						vecs[1].x, vecs[1].y, vecs[1].z,
						vecs[2].x, vecs[2].y, vecs[2].z)
				   bt.handleTypes= (Blender.BezTriple.HandleTypes.FREE, 
									Blender.BezTriple.HandleTypes.FREE)
				   return bt
		   
		   # Create the curve data with one point
		   cu= Blender.Curve.New()
		   cu.appendNurb(bezFromVecs(bezier_vecs[0])) # We must add with a point to start with
		   cu_nurb= cu[0] # Get the first curve just added in the CurveData
		   i= 1 # skip first vec triple because it was used to init the curve
		   while i<len(bezier_vecs):
				   bt_vec_triple= bezier_vecs[i]
				   bt= bezFromVecs(bt_vec_triple)
				   cu_nurb.append(bt)
				   i+=1
		   
		   # Add the Curve into the scene
		   cu.setFlag(cu.getFlag() | 1)  # this fixes a visibility issue with curves in z axis
		   scn= self.scene  #Scene.GetCurrent()
		   ob = self.add(cu,'bezier')
		   return cu,ob
		
		
		
	def addPolyline(self,**kwargs):
		ptList   = kwargs.get('pointList',[[-0.5,0.5,0],[0.5,0.5,0],
		                                   [0.5,-0.5,0],[-0.5,-0.5,0]])
		closed   = kwargs.get('closed',True)
		bezier_vecs = []
		for p in ptList:
			thisPt = Point(p[0],p[1],p[2])
			bezier_vecs.append([thisPt,thisPt,thisPt])
		(cu,ob) = self._bezList2Curve(bezier_vecs)		
		if closed:
			cu[0].setFlagU(1)
		return ob


	
	def addCurveLine(self,**kwargs):
		ptList      = kwargs.get('pointList',[[-0.5,0.5,0],[0.5,0.5,0],
		                                   [0.5,-0.5,0],[-0.5,-0.5,0]])
		closed      = kwargs.get('closed',True)
		smoothness  = kwargs.get('smoothness',1.0) 
		smoothFunction = kwargs.get('smoothFunction',_smoothnessFunction01)
		bezier_vecs = []
		for i,bzpList in enumerate(ptList):
			if i==0 and closed:
				lp = Vector(ptList[-1][0],ptList[-1][1],ptList[-1][2])
				cp = Vector(ptList[0][0],ptList[0][1],ptList[0][2])
				rp = Vector(ptList[1][0],ptList[1][1],ptList[1][2])
			elif i==0 and not closed:
				lp = Vector(ptList[0][0],ptList[0][1],ptList[0][2])
				cp = Vector(ptList[0][0],ptList[0][1],ptList[0][2])
				rp = Vector(ptList[1][0],ptList[1][1],ptList[1][2])
			elif i==len(ptList)-1 and closed:
				lp = Vector(ptList[i-1][0],ptList[i-1][1],ptList[i-1][2])
				cp = Vector(ptList[i][0],ptList[i][1],ptList[i][2])
				rp = Vector(ptList[0][0],ptList[0][1],ptList[0][2])
			elif i==len(ptList)-1 and not closed:
				lp = Vector(ptList[i-1][0],ptList[i-1][1],ptList[i-1][2])
				cp = Vector(ptList[i][0],ptList[i][1],ptList[i][2])
				rp = Vector(ptList[i][0],ptList[i][1],ptList[i][2])
			else:
				lp = Vector(ptList[i-1][0],ptList[i-1][1],ptList[i-1][2])
				cp = Vector(ptList[i][0],ptList[i][1],ptList[i][2])
				rp = Vector(ptList[i+1][0],ptList[i+1][1],ptList[i+1][2])
			dirLeft0 = lp-cp
			dirRight0 = rp-cp
			dirLeft,dirRight = smoothFunction(dirLeft0,dirRight0,smoothness,i,closed)
			lcp = cp+dirLeft
			rcp = cp+dirRight
			#left side of the curve
			leftCtlPt  = Point(lcp[0],lcp[1],lcp[2])
			Pt         = Point(cp[0],cp[1],cp[2])
			rightCtlPt = Point(rcp[0],rcp[1],rcp[2])
			bezier_vecs.append([leftCtlPt,Pt,rightCtlPt])
		(cu,ob) = self._bezList2Curve(bezier_vecs)
		if closed:
			cu[0].setFlagU(1)
		return ob
	
	def addTube(self,**kwargs):
		ptList      = kwargs.get('pointList',[
						[[-3,0,0],[-2,2,0],[0,3,0]],
						[[0,3,0],[2,2,0],[3,0,0]],
		                [[3,0,0],[2,-2,0],[0,-3,0]],
						[[0,-3,0],[-2,-2,0],[-3,0,0]]])
		closed      = kwargs.get('closed',True)
		tubeCurveOb = kwargs.get('tubePath',None)
		tubeShapeOb = kwargs.get('tubeShape',None)
		tubeTaperOb = kwargs.get('tubeTaper',None)
		if tubeCurveOb==None:
			bezier_vecs = []
			for bzpList in ptList:
				leftCtlPt  = Point(bzpList[0][0],bzpList[0][1],bzpList[0][2])
				Pt         = Point(bzpList[1][0],bzpList[1][1],bzpList[1][2])
				rightCtlPt = Point(bzpList[2][0],bzpList[2][1],bzpList[2][2])
				bezier_vecs.append([leftCtlPt,Pt,rightCtlPt])
			(cu,ob) = self._bezList2Curve(bezier_vecs)
			if closed:
				cu[0].setFlagU(1)
		else:
			ob = tubeCurveOb
			cu = tubeCurveOb.data
		if not tubeShapeOb==None:
			cu.bevob = tubeShapeOb
		if not tubeTaperOb==None:
			cu.taperob = tubeTaperOb
		self._ModifyObject(ob,cu,**kwargs)
		return ob
	
	def addWorld(self,**kwargs):
		pass
	
	def drawNow(self,**kwargs):
		xSize = kwargs.get('xSize',1024)
		ySize = kwargs.get('ySize',800)
		overSampleLevel = kwargs.get('oversamplingLevel',16)
		#print 'Image.drawNow() executing'
		self.context = self.scene.getRenderingContext() 
		# enable seperate window for rendering 
		Blender.Scene.Render.EnableDispWin() 
		self.context.imageType = Blender.Scene.Render.JPEG
		if overSampleLevel>0:
			self.context.enableOversampling(True)
			self.context.setOversamplingLevel(overSampleLevel)
		else:
			self.context.enableOversampling(False)			
		self.context.imageSizeX(xSize)
		self.context.imageSizeY(ySize)
		# draw the image 
		self.context.render() 		
	
	def save(self,filename='image.jpg'):
		self.drawNow()
		# save current directory
		oldPath = os.getcwd()
		# for now, force images to be a jpeg
		self.context.imageType = Blender.Scene.Render.JPEG
		(thisPath,thisFilename) = os.path.split(filename)
		print 'thisPath = %s' % thisPath
		print 'thisFilename = %s' % thisFilename
		os.chdir(thisPath+'\\')
		self.context.setRenderPath(thisPath+'\\')
		print os.getcwd()
		self.context.saveRenderedImage(thisFilename) 
		# restore old path
		os.chdir(oldPath)
		print os.getcwd()
class Animation(object):
	pass
	
class BEG(object):
	pass


# This does not work with Blender
#if name=='__main__':
#	# test/demo codes here
#	pass
	
	